14장. RAG 시스템 설계하기
1. RAG는 단순히 벡터DB를 붙이는 것이 아니다
RAG를 처음 접하면 이렇게 생각하기 쉽다.
문서를 벡터DB에 넣는다.
→ 사용자가 질문하면 관련 문서를 찾는다.
→ AI에게 문서를 넣고 답변하게 한다.
큰 흐름은 맞다.
하지만 실제 서비스에서 사용할 RAG 시스템은 이것보다 훨씬 더 많은 요소를 고려해야 한다.
- 어떤 문서를 넣을 것인가
- 문서를 어떻게 수집할 것인가
- 오래된 문서는 어떻게 처리할 것인가
- 문서를 어떤 단위로 나눌 것인가
- 문서 권한은 어떻게 적용할 것인가
- 검색 결과가 맞는지 어떻게 확인할 것인가
- AI가 문서에 없는 내용을 답하지 않게 어떻게 막을 것인가
- 답변에 출처를 어떻게 표시할 것인가
- 사용자가 권한 없는 문서를 물어보면 어떻게 처리할 것인가
RAG는 단순한 AI 기능이 아니다.
문서 관리, 검색, 권한, 보안, 답변 생성, 운영 모니터링이 합쳐진 시스템이다.
그래서 RAG를 만들 때는 “벡터DB에 문서를 넣자”부터 시작하면 위험하다.
먼저 전체 구조를 설계해야 한다.
이 장에서는 RAG 시스템을 실제 서비스에 적용한다고 생각하고, 어떤 순서로 설계해야 하는지 정리한다.
2. RAG 시스템의 전체 구조
RAG 시스템은 크게 두 영역으로 나눌 수 있다.
1. 문서 색인 영역
2. 질문 응답 영역
문서 색인 영역은 사용자가 질문하기 전에 미리 준비하는 영역이다.
문서 수집
→ 텍스트 추출
→ 문서 정제
→ 문서 분할
→ 임베딩 생성
→ 벡터DB 저장
질문 응답 영역은 사용자가 실제로 질문했을 때 동작하는 영역이다.
사용자 질문
→ 사용자 권한 확인
→ 질문 임베딩 생성
→ 관련 문서 검색
→ 검색 결과 재정렬
→ 프롬프트 구성
→ LLM 호출
→ 답변 생성
→ 출처와 함께 반환
전체 흐름을 한 번에 보면 다음과 같다.
[문서 저장소]
↓
[문서 수집기]
↓
[텍스트 추출 / 정제]
↓
[문서 분할]
↓
[임베딩 생성]
↓
[벡터DB 저장]
[사용자 질문]
↓
[인증 / 권한 확인]
↓
[질문 임베딩]
↓
[벡터DB 검색]
↓
[권한 필터 / 최신 문서 필터]
↓
[검색 결과 재정렬]
↓
[LLM 프롬프트 구성]
↓
[답변 생성]
↓
[출처 포함 응답]
이 구조에서 중요한 점은 두 가지다.
첫 번째는 문서를 잘 준비해야 한다는 것이다.
문서가 오래되었거나, 중복되었거나, 권한 정보가 없으면 RAG 답변도 불안정해진다.
두 번째는 질문 시점에 권한과 검색 품질을 함께 봐야 한다는 것이다.
AI가 답변을 잘하는 것보다 먼저, 사용자에게 보여줘도 되는 문서만 검색되는지 확인해야 한다.
색인은 문서를 검색하기 좋은 형태로 미리 가공해 저장하는 과정이다.
RAG에서는 문서를 chunk로 나누고 임베딩해서 벡터DB에 저장하는 작업이 색인에 해당한다.
3. 먼저 RAG의 목적을 정해야 한다
RAG 시스템을 설계하기 전에 가장 먼저 정해야 할 것은 목적이다.
RAG라고 해서 모두 같은 구조가 필요한 것은 아니다.
예를 들어 다음 기능들은 모두 RAG를 사용할 수 있지만 목적이 다르다.
- 사내 문서 검색 챗봇
- 고객센터 상담 보조
- 개발 문서 검색
- 운영 장애 대응 매뉴얼 검색
- 보안 정책 질의응답
- 관리자 기능 도움말
사내 문서 검색 챗봇은 다양한 문서를 넓게 검색해야 한다.
고객센터 상담 보조는 정책 문서와 처리 매뉴얼을 정확하게 찾아야 한다.
개발 문서 검색은 API 이름, 함수명, 에러 코드 같은 키워드 검색이 중요하다.
운영 장애 대응 매뉴얼 검색은 최신 장애 대응 절차와 과거 장애 보고서를 함께 봐야 할 수 있다.
따라서 먼저 다음 질문에 답해야 한다.
- 누가 사용할 것인가?
- 어떤 문서를 대상으로 할 것인가?
- 답변은 얼마나 정확해야 하는가?
- 출처가 반드시 필요한가?
- 사용자의 권한에 따라 문서 접근이 달라지는가?
- 답변이 틀렸을 때 위험도가 큰가?
- 실시간성이 중요한가?
예를 들어 고객센터 상담 보조 RAG라면 다음처럼 목적을 정할 수 있다.
목적:
상담원이 고객 문의 처리 중 회사 정책과 처리 절차를 빠르게 확인할 수 있도록 돕는다.
대상 문서:
- 고객센터 처리 매뉴얼
- 환불 정책
- 결제 장애 처리 절차
- 신고 처리 기준
중요한 기준:
- 최신 정책 우선
- 출처 표시 필수
- 문서에 없는 내용은 답하지 않음
- 상담원이 최종 확인 후 사용
이렇게 목적을 정하면 이후 설계 기준이 명확해진다.
RAG는 “문서를 넣고 질문하게 하는 기능”이 아니라,
특정 업무에서 필요한 지식을 안전하게 찾아주는 시스템이다.
4. 어떤 문서를 넣을지 정한다
RAG 품질은 문서 품질에 크게 좌우된다.
그래서 가장 먼저 해야 할 일은 어떤 문서를 RAG에 넣을지 정하는 것이다.
문서를 무조건 많이 넣는다고 좋은 것은 아니다.
오래된 문서, 중복 문서, 임시 메모, 검토되지 않은 문서가 섞이면 AI가 잘못된 답변을 할 수 있다.
예를 들어 환불 정책을 묻는 질문에 대해 다음 문서들이 모두 검색될 수 있다고 해보자.
- 2023년 환불 정책 초안
- 2024년 환불 정책 개정안
- 2025년 고객센터 임시 처리 메모
- 2026년 최신 환불 정책
이 중에서 어떤 문서가 기준인지 명확하지 않으면 RAG 답변도 흔들린다.
따라서 RAG에 넣을 문서는 기준을 정해야 한다.
포함할 문서:
- 공식 정책 문서
- 최신 운영 매뉴얼
- 승인된 개발 문서
- 장애 대응 절차
- 고객센터 검토 완료 문서
제외할 문서:
- 오래된 초안
- 검토되지 않은 개인 메모
- 중복된 임시 문서
- 폐기된 정책
- 권한 정보가 없는 민감 문서
문서마다 상태를 관리하는 것도 좋다.
문서 상태:
- draft: 초안
- review: 검토 중
- approved: 승인됨
- deprecated: 더 이상 사용하지 않음
RAG 검색 대상은 기본적으로 approved 문서로 제한하는 것이 안전하다.
문서가 폐기되었으면 deprecated 상태로 바꾸고 검색에서 제외한다.
deprecated는 더 이상 사용을 권장하지 않는 상태를 의미한다.
문서에도 적용할 수 있으며, 오래된 정책이나 폐기된 매뉴얼을 검색에서 제외할 때 사용할 수 있다.
5. 문서 소유자를 정해야 한다
RAG 시스템에서 자주 놓치는 부분이 문서 소유자다.
문서를 벡터DB에 넣는 것은 어렵지 않을 수 있다.
하지만 시간이 지나면 문제가 생긴다.
- 이 문서가 최신인지 누가 확인하는가?
- 정책이 바뀌면 누가 수정하는가?
- 충돌하는 문서가 있으면 누가 정리하는가?
- 오래된 문서는 누가 폐기하는가?
문서 소유자가 없으면 RAG는 점점 불안정해진다.
처음에는 잘 동작하더라도, 몇 달 뒤에는 오래된 문서와 최신 문서가 섞일 수 있다.
그래서 문서마다 소유자를 지정하는 것이 좋다.
문서 메타데이터 예시:
- document_id
- title
- owner_team
- owner_user
- status
- updated_at
- review_due_date
예를 들어 다음과 같이 관리할 수 있다.
문서 제목:
결제 실패 및 하트 미반영 처리 매뉴얼
소유 팀:
고객운영팀
검토 담당:
운영 정책 담당자
상태:
approved
마지막 수정일:
2026-04-20
다음 검토 예정일:
2026-07-20
RAG 시스템은 AI 프로젝트이기도 하지만 지식 관리 프로젝트이기도 하다.
문서 소유자와 검토 주기가 없으면 답변 품질을 장기적으로 유지하기 어렵다.
6. 문서 수집 방식을 설계한다
RAG에 사용할 문서를 정했다면, 이제 문서를 어떻게 가져올지 정해야 한다.
문서는 여러 곳에 흩어져 있을 수 있다.
- GitHub 저장소의 Markdown
- Google Docs
- Notion
- Confluence
- PDF
- 사내 Wiki
- DB에 저장된 FAQ
- 고객센터 매뉴얼 시스템
문서 수집 방식은 크게 두 가지다.
1. 수동 업로드
2. 자동 동기화
수동 업로드는 간단하다.
관리자가 파일을 업로드하면 그 파일을 RAG에 넣는다.
관리자 업로드
→ 텍스트 추출
→ 임베딩 생성
→ 벡터DB 저장
초기 PoC에서는 수동 업로드가 좋다.
구현이 쉽고, 문서 범위를 통제하기 쉽기 때문이다.
하지만 운영 단계에서는 자동 동기화가 필요할 수 있다.
매일 새벽 3시
→ Google Docs 변경 문서 확인
→ 수정된 문서만 다시 색인
또는 GitHub 문서는 main 브랜치에 병합될 때 자동으로 색인할 수 있다.
문서 PR 병합
→ GitHub Actions 실행
→ 변경된 Markdown 문서 색인
→ 벡터DB 갱신
문서 수집 방식은 문서의 변경 주기에 맞춰야 한다.
자주 바뀌는 문서:
자동 동기화 필요
거의 바뀌지 않는 문서:
수동 업로드로도 가능
배포와 함께 바뀌는 개발 문서:
CI/CD와 연동 가능
정책 문서:
승인 프로세스 이후 색인 권장
문서 수집을 설계할 때는 “문서를 한 번 넣는 방법”보다 “문서가 바뀌었을 때 어떻게 갱신할 것인가”가 더 중요하다.
7. 텍스트 추출과 정제가 필요하다
문서를 수집했다고 바로 임베딩하면 안 된다.
먼저 텍스트를 추출하고 정제해야 한다.
PDF, HTML, Google Docs, Markdown은 각각 구조가 다르다.
문서를 그대로 텍스트로 뽑으면 불필요한 내용이 섞일 수 있다.
- 페이지 번호
- 목차 반복
- 헤더와 푸터
- 광고나 안내 문구
- 깨진 문자
- 불필요한 공백
- 중복된 제목
- 표 구조 손실
예를 들어 PDF에서 텍스트를 추출했는데 다음처럼 나올 수 있다.
결제 실패 처리 매뉴얼
Page 1 of 12
1. 개요
결제 실패 시 확인 절차는 다음과 같다...
결제 실패 처리 매뉴얼
Page 2 of 12
페이지마다 문서 제목과 페이지 번호가 반복된다.
이런 내용이 계속 들어가면 검색 품질이 떨어질 수 있다.
HTML 문서도 마찬가지다.
- 메뉴
- 사이드바
- 푸터
- 이전/다음 버튼
- 댓글 영역
이런 부분은 실제 답변 근거와 관련이 없을 수 있다.
따라서 정제 과정이 필요하다.
정제 작업:
- 불필요한 헤더/푸터 제거
- 중복 공백 제거
- 깨진 문자 정리
- 문서 제목과 섹션 구조 유지
- 표는 가능한 읽을 수 있는 형태로 변환
- 코드 블록은 보존
특히 개발 문서에서는 코드 블록 보존이 중요하다.
문서 본문:
방송 시작 API는 다음 순서로 처리된다.
코드 예시:
POST /broadcast/start
코드나 API 경로가 깨지면 검색 품질이 떨어진다.
텍스트 정제는 눈에 잘 띄지 않지만 RAG 품질에 큰 영향을 준다.
8. 문서 분할 전략을 정한다
텍스트를 정제한 다음에는 문서를 chunk로 나눈다.
13장에서 설명한 것처럼 chunk 크기는 검색 품질에 큰 영향을 준다.
문서 분할 방식은 문서 종류에 따라 달라야 한다.
8.1 정책 문서
정책 문서는 섹션 단위로 나누는 것이 좋다.
1. 회원 가입
2. 회원 탈퇴
3. 재가입 제한
4. 개인정보 보관
각 섹션은 하나의 정책 주제를 담고 있기 때문이다.
8.2 FAQ 문서
FAQ는 질문과 답변 한 쌍을 하나의 chunk로 나누는 것이 좋다.
Q. 하트 충전 후 반영되지 않으면 어떻게 하나요?
A. 먼저 PG 승인 여부를 확인하고...
FAQ에서 질문과 답변이 분리되면 문맥이 부족해진다.
따라서 Q와 A는 함께 유지해야 한다.
8.3 API 문서
API 문서는 엔드포인트 단위로 나누는 것이 좋다.
POST /broadcast/start
GET /broadcast/{id}
POST /broadcast/stop
각 API의 요청 파라미터, 응답 예시, 에러 코드는 같은 chunk 안에 있는 것이 좋다.
8.4 장애 대응 매뉴얼
장애 대응 매뉴얼은 증상 또는 절차 단위로 나누는 것이 좋다.
Redis timeout 증가 시 확인 절차
DB 커넥션 부족 시 대응 절차
방송방 입장 실패 시 확인 절차
운영자가 질문할 때 보통 증상 중심으로 묻기 때문이다.
Redis timeout이 늘어나면 뭘 봐야 해?
방송 입장이 안 되면 어디부터 확인해?
문서 분할은 일괄적으로 “몇 글자마다 자르기”보다, 문서 구조를 최대한 살리는 것이 좋다.
좋은 분할:
제목, 섹션, FAQ, API 단위 유지
나쁜 분할:
글자 수 기준으로 무조건 자르기
물론 글자 수 기준 분할도 필요할 수 있다.
하지만 가능하면 의미 단위를 먼저 고려해야 한다.
9. 문서 메타데이터를 설계한다
RAG에서 메타데이터는 매우 중요하다.
문서 내용만 저장하면 출처 표시, 권한 제어, 최신 문서 우선 검색이 어렵다.
문서 chunk에는 최소한 다음 정보가 필요하다.
- chunk_id
- document_id
- title
- section
- content
- source_url
- updated_at
- status
- allowed_roles
예를 들어 다음과 같은 구조를 생각할 수 있다.
{
"chunkId": "chunk_001",
"documentId": "doc_payment_manual",
"title": "결제 실패 및 하트 미반영 처리 매뉴얼",
"section": "2. 충전 미반영 처리",
"content": "PG 승인 완료 후 서비스 충전 내역이 없는 경우 충전 처리 로그를 확인한다.",
"sourceUrl": "https://docs.example.com/payment-manual",
"updatedAt": "2026-05-01",
"status": "approved",
"allowedRoles": [
"operation_manager",
"admin"
]
}
메타데이터는 다음 기능에 사용된다.
출처 표시:
title, section, sourceUrl
권한 제어:
allowedRoles
최신 문서 우선:
updatedAt
검색 제외:
status
문서 유형 필터:
documentType
부서별 검색:
ownerTeam, department
처음에는 메타데이터를 최소한으로 시작해도 된다.
하지만 권한과 출처는 처음부터 넣는 것이 좋다.
나중에 추가하려고 하면 이미 색인된 문서를 다시 처리해야 할 수 있다.
메타데이터는 문서 내용 자체가 아니라 문서에 대한 정보다.
제목, 섹션, 출처, 권한, 수정일 같은 값이 메타데이터에 해당한다.
10. 권한 필터는 검색 전에 적용해야 한다
RAG에서 권한 제어는 매우 중요하다.
사용자가 접근할 수 없는 문서가 AI에게 전달되면 안 된다.
잘못된 구조는 다음과 같다.
전체 문서 검색
→ 검색 결과를 AI에게 전달
→ AI가 알아서 권한 고려
이 방식은 위험하다.
AI가 권한 없는 문서를 읽어버린 상태이기 때문이다.
안전한 구조는 다음과 같다.
사용자 인증 확인
→ 사용자 role 확인
→ 접근 가능한 문서만 검색
→ 검색 결과를 AI에게 전달
즉, 권한 필터는 검색 전 또는 검색 단계에서 적용해야 한다.
사용자 role:
operation_manager
검색 대상:
allowedRoles에 operation_manager가 포함된 chunk만
예를 들어 일반 관리자가 정산 정책을 물어봤다고 하자.
질문:
파트너 정산 예외 기준 알려줘.
일반 관리자에게 정산 정책 권한이 없다면 검색 결과가 없어야 한다.
AI에게는 정산 문서가 전달되지 않아야 한다.
답변은 다음처럼 해야 한다.
해당 정보에 접근할 수 있는 문서를 찾을 수 없습니다.
필요한 경우 담당 부서에 권한을 요청해주세요.
권한 제어를 AI에게 맡기면 안 된다.
권한은 서버가 처리해야 한다.
AI의 역할:
허용된 문서를 바탕으로 답변 생성
서버의 역할:
사용자 인증, 권한 확인, 문서 접근 범위 제한
RAG 시스템에서 권한 제어는 보안의 핵심이다.
11. 검색 전략을 정한다
RAG 검색 방식은 하나만 있는 것이 아니다.
기본적으로는 벡터 검색을 사용하지만, 실무에서는 여러 검색 전략을 조합하는 경우가 많다.
대표적인 검색 전략은 다음과 같다.
1. 벡터 검색
2. 키워드 검색
3. 하이브리드 검색
4. 메타데이터 필터 검색
5. reranking
벡터 검색은 의미가 비슷한 문서를 찾는 데 강하다.
질문:
하트 결제했는데 안 들어왔어요.
검색 문서:
결제 승인 후 재화 지급 실패 처리 절차
키워드 검색은 정확한 문자열을 찾는 데 강하다.
질문:
ERR_PAYMENT_409는 뭐야?
검색 문서:
ERR_PAYMENT_409 에러 코드 설명
하이브리드 검색은 둘을 함께 사용한다.
사용자 질문
→ 키워드 검색
→ 벡터 검색
→ 결과 병합
→ 중복 제거
→ 점수 재계산
메타데이터 필터는 검색 범위를 제한한다.
- approved 문서만 검색
- operation 문서만 검색
- 사용자 role이 접근 가능한 문서만 검색
- 최근 1년 이내 문서 우선
reranking은 1차 검색 결과를 다시 정렬한다.
1차 검색 결과 20개
→ 질문과 문서의 관련도를 다시 평가
→ 상위 5개만 LLM에 전달
처음부터 복잡하게 만들 필요는 없다.
초기에는 다음 정도로 시작할 수 있다.
초기 추천:
- 권한 필터
- status = approved 필터
- 벡터 검색 top_k 5
- 출처 표시
이후 검색 품질이 부족하면 하이브리드 검색과 reranking을 추가한다.
12. 프롬프트는 “문서 기반 답변”을 강제해야 한다
RAG에서 LLM에게 보낼 프롬프트는 일반 챗봇 프롬프트와 다르다.
RAG 프롬프트의 핵심은 검색된 문서를 근거로만 답하게 하는 것이다.
예를 들어 다음과 같은 구조가 좋다.
너는 사내 문서를 기반으로 답변하는 AI 도우미다.
규칙:
- 제공된 문서 내용만 근거로 답변한다.
- 문서에 없는 내용은 추측하지 않는다.
- 답을 찾을 수 없으면 "제공된 문서에서 확인할 수 없습니다"라고 말한다.
- 답변에는 근거 문서 제목과 섹션을 포함한다.
- 서로 충돌하는 문서가 있으면 충돌한다고 표시한다.
문서:
[검색된 문서 조각]
사용자 질문:
[질문]
이 규칙이 없으면 AI는 일반 지식을 섞을 수 있다.
예를 들어 문서에는 답이 없는데 AI가 이렇게 답할 수 있다.
일반적으로 환불은 결제 후 7일 이내 가능합니다.
RAG에서는 이런 답변이 위험하다.
검색된 문서에 없으면 모른다고 해야 한다.
제공된 문서에서는 환불 가능 기간을 확인할 수 없습니다.
환불 정책 문서 확인이 필요합니다.
또 출처를 강제해야 한다.
답변 형식:
1. 답변
2. 근거 문서
3. 추가 확인 필요 사항
예를 들면 다음과 같다.
답변:
하트 충전 후 반영되지 않은 경우 먼저 PG 승인 여부를 확인해야 합니다.
PG 승인이 완료되었지만 서비스 충전 내역이 없다면 충전 처리 로그를 확인합니다.
근거 문서:
- 결제 실패 및 하트 미반영 처리 매뉴얼 > 2. 충전 미반영 처리
추가 확인 필요:
- 해당 결제의 PG 승인 여부
- 서비스 충전 처리 로그
RAG 프롬프트는 AI가 똑똑하게 추측하게 만드는 것이 아니라,
AI가 근거 안에서만 답하게 만드는 장치다.
13. 답변에 출처를 표시해야 한다
RAG의 장점 중 하나는 출처를 표시할 수 있다는 점이다.
출처가 없으면 사용자는 AI 답변을 검증하기 어렵다.
출처 없는 답변:
회원 탈퇴 후 7일 동안 재가입할 수 없습니다.
출처 있는 답변:
회원 탈퇴 후 동일 계정 정보로는 7일 동안 재가입할 수 없습니다.
근거:
회원 정책 문서 > 3. 탈퇴 및 재가입
출처를 표시할 때는 가능한 한 구체적인 단위가 좋다.
나쁜 출처:
회원 정책 문서
좋은 출처:
회원 정책 문서 > 3. 탈퇴 및 재가입 > 재가입 제한
출처에는 다음 정보를 포함할 수 있다.
- 문서 제목
- 섹션 제목
- 문서 링크
- 마지막 수정일
- 관련 문장 일부
예를 들어 다음처럼 보여줄 수 있다.
근거 문서:
1. 결제 실패 및 하트 미반영 처리 매뉴얼
- 섹션: 2. 충전 미반영 처리
- 마지막 수정일: 2026-05-01
2. 환불 처리 기준
- 섹션: 4. 이미 사용된 재화 처리
- 마지막 수정일: 2026-04-15
출처를 표시하면 사용자가 원문을 확인할 수 있다.
또 답변이 틀렸을 때 원인을 찾기 쉽다.
답변이 틀림
→ 어떤 문서가 근거로 쓰였는지 확인
→ 문서가 오래됐는지 확인
→ 검색이 잘못됐는지 확인
→ 프롬프트가 잘못됐는지 확인
출처 표시는 단순히 신뢰감을 주기 위한 UI가 아니다.
RAG 운영과 품질 개선을 위한 핵심 정보다.
14. 문서 충돌을 처리해야 한다
RAG에서 자주 생기는 문제가 문서 충돌이다.
서로 다른 문서가 다른 내용을 말할 수 있다.
예를 들어 검색 결과에 다음 두 문서가 들어왔다고 해보자.
문서 A:
회원 탈퇴 후 30일 동안 재가입할 수 없다.
문서 B:
회원 탈퇴 후 7일 동안 재가입할 수 없다.
AI가 둘 중 하나를 임의로 선택하면 위험하다.
문서 충돌이 있을 때는 충돌한다고 알려야 한다.
검색된 문서에서 서로 다른 기준이 확인됩니다.
- 회원 정책 문서 v1: 탈퇴 후 30일 재가입 제한
- 회원 정책 문서 v2: 탈퇴 후 7일 재가입 제한
최신 기준 확인이 필요합니다.
더 좋은 방식은 문서 메타데이터로 최신 문서를 우선하는 것이다.
문서 A updated_at: 2024-01-10
문서 B updated_at: 2026-04-01
→ 문서 B 우선
하지만 최신 문서라고 항상 맞는 것은 아니다.
초안 문서가 최신일 수도 있기 때문이다.
그래서 status도 함께 봐야 한다.
문서 A:
status = approved
updated_at = 2024-01-10
문서 B:
status = draft
updated_at = 2026-04-01
이 경우 approved 문서를 우선해야 할 수 있다.
문서 충돌을 줄이려면 다음이 필요하다.
- 문서 상태 관리
- 문서 소유자 지정
- 최신 문서 표시
- deprecated 문서 검색 제외
- 충돌 발생 시 확인 필요 표시
RAG는 문서를 기반으로 답하기 때문에, 문서 자체가 충돌하면 답변도 불안정해진다.
문서 충돌 처리는 RAG 운영에서 반드시 고려해야 한다.
15. 답변 실패 상황을 설계해야 한다
RAG는 항상 답을 찾을 수 있는 것은 아니다.
검색 결과가 없을 수도 있고,
검색 결과는 있지만 답변에 필요한 내용이 없을 수도 있다.
이런 상황을 미리 설계해야 한다.
15.1 검색 결과가 없는 경우
사용자가 질문했지만 관련 문서를 찾지 못한 경우다.
질문:
파트너 정산 예외 승인자는 누구야?
검색 결과:
없음
답변은 다음처럼 해야 한다.
제공된 문서에서 해당 내용을 확인할 수 없습니다.
정산 정책 문서 또는 담당 부서 확인이 필요합니다.
15.2 검색 결과는 있지만 답이 없는 경우
관련 문서는 찾았지만 질문에 직접 답할 내용이 없는 경우다.
검색 문서:
정산 일정 문서
질문:
정산 예외 승인자는 누구야?
문서는 정산 일정만 설명하고 승인자는 설명하지 않는다.
이때도 추측하면 안 된다.
검색된 문서에는 정산 일정은 설명되어 있지만,
정산 예외 승인자에 대한 내용은 확인되지 않습니다.
15.3 권한이 없는 경우
사용자에게 해당 문서를 볼 권한이 없는 경우다.
해당 정보에 접근할 수 있는 문서를 찾을 수 없습니다.
필요한 경우 권한 요청 절차를 진행해주세요.
주의할 점은 “권한 없는 문서가 존재한다”고 알려주는 것도 민감할 수 있다는 것이다.
따라서 답변은 조심해야 한다.
나쁜 답변:
정산 정책 문서가 있지만 사용자에게 권한이 없습니다.
더 안전한 답변:
현재 권한으로 확인 가능한 문서에서는 해당 내용을 찾을 수 없습니다.
RAG는 답변하는 능력만큼 답변하지 않는 능력도 중요하다.
16. RAG 결과를 평가하는 기준
RAG를 만들었다면 품질을 평가해야 한다.
AI 답변만 보고 “괜찮아 보인다”로 판단하면 안 된다.
RAG는 검색과 생성이 결합된 구조이므로 평가도 나눠서 해야 한다.
1. 검색 품질 평가
2. 답변 품질 평가
검색 품질 평가는 관련 문서를 잘 찾았는지 보는 것이다.
평가 항목:
- 기대 문서가 top 3 안에 있는가?
- 기대 문서가 top 5 안에 있는가?
- 관련 없는 문서가 너무 많이 섞이지 않았는가?
- 최신 문서가 우선 검색되었는가?
- 권한 없는 문서가 검색되지 않았는가?
답변 품질 평가는 AI가 검색된 문서를 바탕으로 잘 답했는지 보는 것이다.
평가 항목:
- 문서 내용과 일치하는가?
- 문서에 없는 내용을 추측하지 않았는가?
- 출처가 표시되었는가?
- 답변이 사용자의 질문에 직접 답하는가?
- 확인 필요 사항을 잘 구분했는가?
테스트 질문 세트를 만들어두는 것이 좋다.
질문:
하트 충전 후 반영이 안 되면 어떻게 처리해?
기대 문서:
결제 실패 및 하트 미반영 처리 매뉴얼
기대 답변:
PG 승인 여부 확인
충전 처리 로그 확인
재처리 대상 판단
이미 사용된 하트는 환불 제외
이런 테스트 질문을 여러 개 만들어두면 프롬프트, chunk 크기, 모델, 검색 방식을 바꿨을 때 비교할 수 있다.
RAG 품질은 감으로 관리하면 안 된다.
샘플 질문과 기대 결과를 기준으로 관리해야 한다.
17. 운영 로그를 남겨야 한다
RAG 시스템을 운영하려면 로그가 필요하다.
답변이 이상했을 때 원인을 추적하려면 다음 정보를 알아야 한다.
- 사용자가 어떤 질문을 했는가?
- 어떤 문서가 검색되었는가?
- 검색 점수는 얼마였는가?
- 어떤 문서가 AI에게 전달되었는가?
- 어떤 모델을 사용했는가?
- 어떤 프롬프트 버전을 사용했는가?
- AI가 어떤 답변을 했는가?
- 사용자의 권한은 무엇이었는가?
하지만 로그에는 민감 정보가 포함될 수 있다.
따라서 전체 원문을 무조건 저장하면 안 된다.
권장 로그는 다음과 같다.
- request_id
- user_id
- user_role
- question_hash 또는 마스킹된 질문
- retrieved_chunk_ids
- retrieved_scores
- model_name
- prompt_version
- input_tokens
- output_tokens
- latency_ms
- status
- created_at
예시는 다음과 같다.
{
"requestId": "rag_req_123",
"userId": "admin_100",
"userRole": "operation_manager",
"questionHash": "sha256:...",
"retrievedChunkIds": [
"chunk_001",
"chunk_018",
"chunk_042"
],
"retrievedScores": [
0.91,
0.84,
0.77
],
"modelName": "example-ai-model",
"promptVersion": "rag-v1.2",
"inputTokens": 3200,
"outputTokens": 450,
"latencyMs": 4100,
"status": "success",
"createdAt": "2026-05-04T10:30:00+09:00"
}
이런 로그가 있으면 문제를 분석할 수 있다.
답변이 틀림
→ 검색된 chunk 확인
→ 검색이 잘못됐는지 확인
→ 문서가 오래됐는지 확인
→ 프롬프트 버전 확인
→ 모델 변경 영향 확인
RAG 운영에서 로그는 품질 개선의 기본이다.
18. RAG를 처음 만들 때의 추천 범위
처음부터 완벽한 RAG 시스템을 만들려고 하면 복잡해진다.
처음에는 범위를 작게 잡는 것이 좋다.
추천하는 1차 범위는 다음과 같다.
대상:
고객센터 처리 매뉴얼 20~50개 문서
기능:
상담원이 질문하면 관련 문서를 근거로 답변
제약:
- 승인된 문서만 사용
- 운영팀 권한 사용자만 사용
- 답변에는 출처 표시
- 문서에 없으면 모른다고 답변
- 대화 저장은 최소화
처음부터 넣지 않아도 되는 기능도 있다.
초기에는 제외해도 되는 기능:
- 모든 사내 문서 연결
- 복잡한 권한 모델
- 실시간 문서 동기화
- 자동 문서 충돌 해결
- 다국어 검색
- 에이전트 자동 실행
초기 RAG는 작고 명확한 업무에 적용하는 것이 좋다.
예를 들어 다음처럼 시작할 수 있다.
1단계:
고객센터 결제 문의 매뉴얼만 대상으로 RAG 구성
2단계:
환불, 신고, 계정 문의 매뉴얼 추가
3단계:
권한별 문서 접근 제어 강화
4단계:
운영 로그와 품질 평가 대시보드 추가
5단계:
사내 개발 문서 검색으로 확장
RAG는 문서가 많아질수록 품질 관리가 어려워진다.
작은 범위에서 검색 품질과 답변 품질을 검증한 뒤 확장하는 것이 안전하다.
19. RAG 설계 체크리스트
RAG 시스템을 설계할 때는 다음 체크리스트를 사용할 수 있다.
19.1 목적과 범위
- RAG를 어떤 업무에 사용할 것인가?
- 사용자는 누구인가?
- 어떤 질문에 답해야 하는가?
- 답변하지 말아야 할 질문은 무엇인가?
- 초기 범위는 어디까지인가?
19.2 문서
- 사용할 문서 목록이 정리되어 있는가?
- 문서가 최신인가?
- 중복되거나 충돌하는 문서는 없는가?
- 문서 소유자가 있는가?
- 문서 상태가 관리되는가?
19.3 권한
- 사용자 role이 정의되어 있는가?
- 문서별 allowedRoles가 있는가?
- 검색 전에 권한 필터가 적용되는가?
- 권한 없는 문서는 AI에게 전달되지 않는가?
19.4 검색
- chunk 단위가 적절한가?
- 벡터 검색을 사용할 것인가?
- 키워드 검색도 함께 사용할 것인가?
- top_k 값은 적절한가?
- reranking이 필요한가?
- 최신 문서를 우선할 것인가?
19.5 답변 생성
- 문서 기반으로만 답변하게 하는가?
- 문서에 없으면 모른다고 답하는가?
- 출처를 표시하는가?
- 문서 충돌 시 확인 필요로 표시하는가?
19.6 운영
- 검색 결과 로그를 남기는가?
- 프롬프트 버전을 관리하는가?
- 토큰 사용량을 기록하는가?
- 답변 품질을 평가할 샘플 질문이 있는가?
- 민감 정보가 로그에 남지 않는가?
이 체크리스트를 보면 알 수 있듯이 RAG는 단순 개발 작업이 아니다.
문서, 권한, 검색, 답변, 운영을 함께 설계해야 한다.
20. 정리
RAG는 AI가 내부 문서나 최신 정보를 근거로 답변하게 만드는 강력한 구조다.
하지만 RAG를 단순히 벡터DB와 LLM을 연결하는 기능으로 보면 안 된다.
운영 가능한 RAG 시스템을 만들려면 문서 수집, 정제, 분할, 임베딩, 벡터DB 저장, 권한 필터, 검색 전략, 프롬프트, 출처 표시, 로그, 품질 평가까지 함께 설계해야 한다.
특히 중요한 것은 세 가지다.
1. 좋은 문서를 넣어야 한다.
2. 사용자가 볼 수 있는 문서만 검색해야 한다.
3. 문서에 없는 내용은 답하지 않아야 한다.
RAG 품질은 LLM 성능만으로 결정되지 않는다.
문서가 오래되었거나, chunk가 잘못 나뉘었거나, 검색 결과가 부정확하거나, 권한 필터가 빠져 있으면 답변 품질은 떨어진다.
RAG는 AI 프로젝트인 동시에 지식 관리 프로젝트다.
이 장에서 기억해야 할 핵심은 하나다.
RAG 시스템의 목표는 AI가 더 많이 말하게 하는 것이 아니라,
올바른 문서를 근거로 필요한 답만 하게 만드는 것이다.
14장 핵심 요약
| 핵심 내용 | 설명 |
|---|---|
| RAG는 단순한 벡터DB 연결이 아니다 | 문서 관리, 검색, 권한, 답변 생성, 운영 로그가 함께 필요한 시스템이다. |
| 문서 색인과 질문 응답 영역으로 나뉜다 | 문서를 미리 수집·분할·임베딩하고, 질문 시 관련 문서를 검색해 답변한다. |
| 목적을 먼저 정해야 한다 | 사내 문서 검색, 상담 보조, 개발 문서 검색 등 목적에 따라 설계가 달라진다. |
| 문서 품질이 답변 품질을 좌우한다 | 오래된 문서, 초안, 중복 문서는 RAG 답변을 불안정하게 만든다. |
| 문서 소유자가 필요하다 | 문서의 최신성, 폐기, 충돌 해결을 담당할 주체가 있어야 한다. |
| 텍스트 추출과 정제가 필요하다 | 헤더, 푸터, 중복 문구, 깨진 문자 등을 정리해야 검색 품질이 좋아진다. |
| 문서 분할 전략이 중요하다 | 정책은 섹션 단위, FAQ는 질문-답변 단위, API 문서는 엔드포인트 단위가 적합하다. |
| 메타데이터는 필수다 | 출처 표시, 권한 제어, 최신 문서 우선, 문서 상태 필터링에 사용된다. |
| 권한 필터는 검색 전에 적용해야 한다 | 사용자가 접근 가능한 문서만 검색하고 AI에게 전달해야 한다. |
| RAG 프롬프트는 문서 기반 답변을 강제해야 한다 | 문서에 없는 내용은 추측하지 않고 확인 불가로 답하게 해야 한다. |
| 출처 표시는 검증을 가능하게 한다 | 문서 제목, 섹션, 링크, 수정일을 제공하면 사용자가 원문을 확인할 수 있다. |
| 문서 충돌을 처리해야 한다 | 서로 다른 문서가 다른 내용을 말하면 충돌로 표시하거나 최신 승인 문서를 우선해야 한다. |
| 로그와 평가가 필요하다 | 어떤 문서가 검색되었고 어떤 프롬프트와 모델이 사용되었는지 추적해야 한다. |
| 작게 시작해 확장하는 것이 좋다 | 처음에는 제한된 문서와 사용자 범위에서 품질을 검증한 뒤 확장하는 것이 안전하다. |